/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
 */
package td.client.presenter;

import java.util.Date;

import td.client.ClientState;
import td.client.event.ThinkerLoginEvent;
import td.client.presenter.handlers.LoginJoinUiHandlers;
import td.domain.DemoStore;
import td.domain.Thinker;
import td.shared.action.result.JoinLoginResult;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.mvp.client.PresenterWidget;
import com.gwtplatform.mvp.client.proxy.RevealRootPopupContentEvent;

/**
 * @author Artem Shamsutdinov
 * 
 */
public class LoginJoinPresenter extends
		PresenterWidget<LoginJoinUiHandlers.MyView> implements
		LoginJoinUiHandlers {

	@Inject
	WaitPresenter waitPresenter;

	@Inject
	ErrorPresenter errorPresenter;

	@Inject
	DispatchAsync dispatchAsync;

	@Inject
	ClientState state;

	LoginJoinPresenter self;

	AsyncCallback<JoinLoginResult> loginJoinCallback = new AsyncCallback<JoinLoginResult>() {

		@Override
		public void onFailure(final Throwable caught) {
			RevealRootPopupContentEvent.fire(self, errorPresenter);
			errorPresenter.onError(caught.getMessage());
			waitPresenter.hide();
		}

		@Override
		public void onSuccess(final JoinLoginResult result) {
			switch (result.getStatus()) {
			case SUCCESS:
				String thinkerId = result.getThinkerPersonalId();
				state.setSessionCode(result.getSessionCode());
				state.setThinkerId(thinkerId);
				boolean joining = result.isJustJoined();
				ThinkerLoginEvent loginEvent = new ThinkerLoginEvent(thinkerId,
						joining);
				getEventBus().fireEvent(loginEvent);
				getView().hide();
				break;
			default:
				getView().onError(result.getErrorMessage());
				break;
			}
			waitPresenter.hide();
		}
	};

	@Inject
	public LoginJoinPresenter(final EventBus eventBus, final MyView view) {
		super(eventBus, view);
		view.setUiHandlers(this);
		this.self = this;
	}

	@Override
	protected void onBind() {
		super.onBind();
	}

	@Override
	protected void onReveal() {
		super.onReveal();
		getView().onReveal();
	}

	@Override
	public void submitJoinRequest(String thinkerId, String password,
			String email) {
		// JoinAction joinAction = new JoinAction(thinkerId, password, email);
		// dispatchAsync.execute(joinAction, loginJoinCallback);
		// RevealRootPopupContentEvent.fire(this, waitPresenter);

		// FIXME: Temporary, for the demo
		if (thinkerId == null || thinkerId.length() < 1) {
			getView().onError("Thinker ID must be at least 1 character long");
			return;
		}
		if (password == null || password.length() < 1) {
			getView().onError("Password must be at least 1 character long");
			return;
		}
		if (email == null || email.length() < 1) {
			getView().onError("EMail must be at least 1 character long");
			return;
		}
		if (DemoStore.db().getThinkers().get(thinkerId) != null) {
			getView().onError("Thinker '" + thinkerId + "' already exists");
			return;
		}
		state.setSessionCode("blah");
		state.setThinkerId(thinkerId);
		Thinker thinker = new Thinker(email, thinkerId, password, new Date());
		DemoStore.setId(thinker);
		DemoStore.db().getThinkers().put(thinkerId, thinker);
		state.setThinker(thinker);
		ThinkerLoginEvent loginEvent = new ThinkerLoginEvent(thinkerId, true);
		getEventBus().fireEvent(loginEvent);
		getView().hide();
	}

	@Override
	public void submitLoginRequest(String thinkerId, String password) {
		// LoginAction loginAction = new LoginAction(thinkerId, password);
		// dispatchAsync.execute(loginAction, loginJoinCallback);
		// RevealRootPopupContentEvent.fire(this, waitPresenter);

		// FIXME: Temorary, for the demo
		if (thinkerId == null || thinkerId.length() < 1) {
			getView().onError("Thinker ID must be at least 1 character long");
			return;
		}
		if (password == null || password.length() < 1) {
			getView().onError("Password must be at least 1 character long");
			return;
		}
		Thinker thinker = DemoStore.db().getThinkers().get(thinkerId);
		if (thinker == null) {
			getView().onError("Thinker does not exist");
			return;
		}
		if (!thinker.getPasswordDigest().equals(password)) {
			getView().onError("Passwords don't match.");
			return;
		}
		state.setThinker(thinker);
		state.setSessionCode("blah");
		state.setThinkerId(thinkerId);
		ThinkerLoginEvent loginEvent = new ThinkerLoginEvent(thinkerId, false);
		getEventBus().fireEvent(loginEvent);
		getView().hide();
	}
}
